# -*- coding: utf-8 -*-
"""
统一响应结果封装类

提供标准化的API响应格式，包含状态码、消息和数据字段。
支持链式调用和泛型数据类型。

@author: wechat_robot
@created: 2025-08-28
"""

from typing import TypeVar, Generic, Optional, Any, Dict, Tuple
from dataclasses import dataclass
import json
from flask import jsonify as flask_jsonify

# 泛型类型变量
T = TypeVar('T')


@dataclass
class ApiResponse(Generic[T]):
    """
    统一API响应封装类
    
    Attributes:
        code (int): 响应状态码
        message (str): 响应消息
        data (T): 响应数据，支持泛型
        success (bool): 是否成功
    """
    
    # 状态码常量
    SUCCESS_CODE = 200
    FAIL_CODE = 500
    UNAUTHORIZED_CODE = 401
    FORBIDDEN_CODE = 403
    NOT_FOUND_CODE = 404
    VALIDATION_ERROR_CODE = 422
    
    def __init__(self, code: int = SUCCESS_CODE, message: str = "", data: Optional[T] = None):
        self.code = code
        self.message = message
        self.data = data
        self.success = code == self.SUCCESS_CODE
    
    @classmethod
    def ok(cls, data: Optional[T] = None, message: str = "操作成功") -> 'ApiResponse[T]':
        """
        创建成功响应
        
        Args:
            data: 响应数据
            message: 响应消息
            
        Returns:
            ApiResponse: 成功响应对象
        """
        return cls(code=cls.SUCCESS_CODE, message=message, data=data)
    
    @classmethod
    def fail(cls, message: str = "操作失败", code: int = None, data: Optional[T] = None) -> 'ApiResponse[T]':
        """
        创建失败响应
        
        Args:
            message: 错误消息
            code: 错误状态码，默认为500
            data: 响应数据
            
        Returns:
            ApiResponse: 失败响应对象
        """
        error_code = code if code is not None else cls.FAIL_CODE
        return cls(code=error_code, message=message, data=data)
    
    @classmethod
    def unauthorized(cls, message: str = "未授权访问") -> 'ApiResponse[T]':
        """
        创建未授权响应
        
        Args:
            message: 错误消息
            
        Returns:
            ApiResponse: 未授权响应对象
        """
        return cls(code=cls.UNAUTHORIZED_CODE, message=message)
    
    @classmethod
    def forbidden(cls, message: str = "禁止访问") -> 'ApiResponse[T]':
        """
        创建禁止访问响应
        
        Args:
            message: 错误消息
            
        Returns:
            ApiResponse: 禁止访问响应对象
        """
        return cls(code=cls.FORBIDDEN_CODE, message=message)
    
    @classmethod
    def not_found(cls, message: str = "资源不存在") -> 'ApiResponse[T]':
        """
        创建资源不存在响应
        
        Args:
            message: 错误消息
            
        Returns:
            ApiResponse: 资源不存在响应对象
        """
        return cls(code=cls.NOT_FOUND_CODE, message=message)
    
    @classmethod
    def validation_error(cls, message: str = "参数验证失败", data: Optional[T] = None) -> 'ApiResponse[T]':
        """
        创建参数验证失败响应
        
        Args:
            message: 错误消息
            data: 验证错误详情
            
        Returns:
            ApiResponse: 参数验证失败响应对象
        """
        return cls(code=cls.VALIDATION_ERROR_CODE, message=message, data=data)
        
    @classmethod
    def ok_response(cls, data: Optional[T] = None, message: str = "操作成功", status_code: int = None) -> Tuple:
        """
        创建成功响应并直接返回Flask响应对象
        
        Args:
            data: 响应数据
            message: 响应消息
            status_code: HTTP状态码，默认为200
            
        Returns:
            Tuple: (jsonify响应, HTTP状态码)
        """
        return cls.ok(data=data, message=message).jsonify(status_code=status_code)
    
    @classmethod
    def fail_response(cls, message: str = "操作失败", code: int = None, data: Optional[T] = None, status_code: int = None) -> Tuple:
        """
        创建失败响应并直接返回Flask响应对象
        
        Args:
            message: 错误消息
            code: 错误状态码
            data: 响应数据
            status_code: HTTP状态码，默认为500
            
        Returns:
            Tuple: (jsonify响应, HTTP状态码)
        """
        return cls.fail(message=message, code=code, data=data).jsonify(status_code=status_code)
    
    def is_success(self) -> bool:
        """
        判断响应是否成功
        
        Returns:
            bool: 是否成功
        """
        return self.success
    
    def is_error(self) -> bool:
        """
        判断响应是否失败
        
        Returns:
            bool: 是否失败
        """
        return not self.success
    
    def to_dict(self) -> Dict[str, Any]:
        """
        转换为字典格式
        
        Returns:
            Dict: 字典格式的响应数据
        """
        return {
            "code": self.code,
            "message": self.message,
            "data": self.data,
            "success": self.success
        }
    
    def to_json(self) -> str:
        """
        转换为JSON字符串
        
        Returns:
            str: JSON格式的响应数据
        """
        return json.dumps(self.to_dict(), ensure_ascii=False, default=str)
        
    def jsonify(self, status_code: int = None) -> Tuple:
        """
        转换为Flask响应对象
        
        Args:
            status_code: HTTP状态码，默认使用响应对象的code字段
            
        Returns:
            Tuple: (jsonify响应, HTTP状态码)
        """
        response_code = status_code if status_code is not None else (200 if self.success else 500)
        return flask_jsonify(self.to_dict()), response_code
    
    def __str__(self) -> str:
        """
        字符串表示
        
        Returns:
            str: 响应对象的字符串表示
        """
        return f"ApiResponse(code={self.code}, message='{self.message}', success={self.success})"
    
    def __repr__(self) -> str:
        """
        对象表示
        
        Returns:
            str: 响应对象的详细表示
        """
        return self.__str__()
        
    # 移除 __call__ 方法，因为它与 Flask 的调用方式不兼容


# 便捷函数，提供更简洁的调用方式
def success(data: Optional[T] = None, message: str = "操作成功") -> ApiResponse[T]:
    """
    创建成功响应的便捷函数
    
    Args:
        data: 响应数据
        message: 响应消息
        
    Returns:
        ApiResponse: 成功响应对象
    """
    return ApiResponse.ok(data=data, message=message)





def error(message: str = "操作失败", code: int = None, data: Optional[T] = None) -> ApiResponse[T]:
    """
    创建失败响应的便捷函数
    
    Args:
        message: 错误消息
        code: 错误状态码
        data: 响应数据
        
    Returns:
        ApiResponse: 失败响应对象
    """
    return ApiResponse.fail(message=message, code=code, data=data)


def ok_response(data: Optional[T] = None, message: str = "操作成功", status_code: int = None) -> Tuple:
    """
    创建成功响应并直接返回Flask响应对象的便捷函数
    
    Args:
        data: 响应数据
        message: 响应消息
        status_code: HTTP状态码，默认为200
        
    Returns:
        Tuple: (jsonify响应, HTTP状态码)
    """
    return ApiResponse.ok_response(data=data, message=message, status_code=status_code)


def fail_response(message: str = "操作失败", code: int = None, data: Optional[T] = None, status_code: int = None) -> Tuple:
    """
    创建失败响应并直接返回Flask响应对象的便捷函数
    
    Args:
        message: 错误消息
        code: 错误状态码
        data: 响应数据
        status_code: HTTP状态码，默认为500
        
    Returns:
        Tuple: (jsonify响应, HTTP状态码)
    """
    return ApiResponse.fail_response(message=message, code=code, data=data, status_code=status_code)


# 类型别名，提供更好的类型提示
Response = ApiResponse
R = ApiResponse  # 与Java版本保持一致的简短别名